import { SystemEventType, Game, game, JsonAsset, assetManager, Asset } from "cc";
import playerMgr from "./playMgr";
import { LocalCache } from "../utils/LocalCache";
import { MathRandom } from "../utils/UtilsMath";
import { Notifications } from "../easyFramework/notifications";
import DataManager from "./DataManager";
import GDef from "./GDef";

interface armData {
    type: number,
    tid: number,
    pos: number,
}
interface eggData {
    tid: number,
    time: number,
}

//游戏世界数据层
class GD {
    playerMgr: playerMgr//玩家信息管理
    constructor() {
        this.playerMgr = new playerMgr;
    }

    private level: number = 0;//關卡
    private coinNum: number = 0;//金币
    private armList: Array<armData> = [];//我方
    private unlockHunter: Array<number> = [];//解锁猎人
    private unlockDino: Array<number> = [];//解锁恐龙
    private castHuman: number = 1;//召唤猎人次数
    private castDino: number = 1;//召唤恐龙次数
    private savedDino: Array<number> = [];//储存的恐龙次数
    private savedHunter: Array<number> = [];//储存的獵人次数
    private eggList: Array<eggData> = [];//储存的獵人次数
    private castHunterAdCount: number = 0;//广告次数
    private castDinoAdCount: number = 0;//广告次数
    private roundCoin: number = 0;
    public audioEnable: boolean = true;
    public intTeach: number = 0;
    public intOnlineTime: number = 0;
    init() {
        this.logDevelop();
        this.playerMgr.init();
        //监听切换后台
        cc.game.on(Game.EVENT_HIDE, () => {
            console.log("监听切换后台");
            this.setOnlineTime(new Date().getTime());
            game.pause();//暂停游戏
        });
        cc.game.on(Game.EVENT_SHOW, () => {
            console.log("监听恢复游戏");
            this.emit(GDef.wdEvent.resume);
            game.resume();//恢复游戏
        });
        let num = LocalCache.getItem("level");//获取关卡
        if (!num) {
            num = 1;
        }
        this.level = parseInt(num);
        LocalCache.setItem("level", this.level);

        let num2 = LocalCache.getItem("coin");//获取玩家金币
        if (!num2) {
            num2 = 100;
        }
        this.coinNum = parseInt(num2);
        LocalCache.setItem("coin", this.coinNum);

        let castHuman = LocalCache.getItem("castHuman");//获取玩家金币
        if (!castHuman) {
            castHuman = 0;
        }
        this.castHuman = parseInt(castHuman);
        LocalCache.setItem("castHuman", this.castHuman);

        let castDino = LocalCache.getItem("castDino");//获取玩家金币
        if (!castDino) {
            castDino = 0;
        }
        this.castDino = parseInt(castDino);
        LocalCache.setItem("castDino", this.castDino);

        let castHunterAdCount = LocalCache.getItem("castHunterAdCount");//获取玩家金币
        if (!castHunterAdCount) {
            castHunterAdCount = 0;
        }
        this.castHunterAdCount = parseInt(castHunterAdCount);
        LocalCache.setItem("castHunterAdCount", this.castHunterAdCount);

        let castDinoAdCount = LocalCache.getItem("castDinoAdCount");//获取玩家金币
        if (!castDinoAdCount) {
            castDinoAdCount = 0;
        }
        this.castDinoAdCount = parseInt(castDinoAdCount);
        LocalCache.setItem("castDinoAdCount", this.castDinoAdCount);

        let Audio = LocalCache.getItem("Audio")
        if (!Audio) {
            LocalCache.setItem("Audio", 1);
            this.audioEnable = true;
        } else {
            this.audioEnable = (Audio == 1 ? true : false);
        }

        let teach = LocalCache.getItem("teach");//获取关卡
        if (!teach) {
            LocalCache.setItem("teach", 0);
            teach = 0;
        }
        this.intTeach = parseInt(teach);

        let onlineTime = LocalCache.getItem("onlineTime");//获取关卡
        if (!onlineTime) {
            onlineTime = new Date().getTime();
            LocalCache.setItem("onlineTime", onlineTime);
        }
        this.intOnlineTime = parseInt(onlineTime);

        //我方猎人恐龙数据初始化
        this.initPlayerArm();
        //我方猎人恐龙数据初始化
        this.initUnlockHunter();
        this.initUnlockDino();
    }

    initPlayerArm() {
        this.armList = LocalCache.getItem("arm");//获取皮肤数据
        if (!this.armList) {
            let dataList: armData[] = [];
            for (let i = 15; i < 30; i++) {
                var info: armData = {
                    type: -1,//1：human表，2：dino表
                    tid: -1,//表Tid
                    pos: i,//cell的索引
                }
                if (i == 17) {
                    info.type = 1;
                    info.tid = 1;
                }
                if (i == 27) {
                    info.type = 2;
                    info.tid = 1;
                }
                // if(i < 24)
                // {
                //     info.type = 2;
                //     info.tid = (i - 15) * 2 + 2;
                //     // info.tid = 15;
                // }
                dataList.push(info)
            }
            this.armList = dataList;
            LocalCache.setItem("arm", this.armList);
        }

        this.savedDino = LocalCache.getItem("savedDino");
        if (!this.savedDino) {
            this.savedDino = [];
            LocalCache.setItem("savedDino", this.savedDino);
        }
        this.savedHunter = LocalCache.getItem("savedHunter");
        if (!this.savedHunter) {
            this.savedHunter = [];
            LocalCache.setItem("savedHunter", this.savedHunter);
        }
        this.eggList = LocalCache.getItem("eggList");
        if (!this.eggList) {
            this.eggList = [];
            LocalCache.setItem("eggList", this.eggList);
        }
        console.log("init");
        console.log("init");
        console.log("init");
        console.log("init");
        console.log(this.armList);
        console.log(this.eggList);
    }
    initUnlockHunter() {
        this.unlockHunter = LocalCache.getItem("unlockHunter");//获取皮肤数据
        if (!this.unlockHunter) {
            this.unlockHunter = [];
            LocalCache.setItem("unlockHunter", this.unlockHunter);
        }
    }
    initUnlockDino() {
        this.unlockDino = LocalCache.getItem("unlockDino");//获取皮肤数据
        if (!this.unlockDino) {
            this.unlockDino = [];
            LocalCache.setItem("unlockDino", this.unlockDino);
        }
    }
    addTeach() {
        let teach = LocalCache.getItem("teach");//获取关卡
        if (!teach) {
            LocalCache.setItem("teach", 0);
            teach = 0;
        }
        this.intTeach = parseInt(teach) + 1;
        LocalCache.setItem("teach", this.intTeach);
    }
    getSavedDino() {
        return this.savedDino;
    }
    addSavedDino(tid: number) {
        this.savedDino.push(tid)
        LocalCache.setItem("savedDino", this.savedDino);
        this.emit(GDef.wdEvent.updateCastDino);
    }
    decSavedDino() {
        this.savedDino.splice(0, 1);
        LocalCache.setItem("savedDino", this.savedDino);
    }
    getSavedHunter() {
        return this.savedHunter;
    }
    decSavedHunter() {
        this.savedHunter.splice(0, 1);
        LocalCache.setItem("savedHunter", this.savedHunter);
    }
    addSavedHunter(tid: number) {
        this.savedHunter.push(tid)
        LocalCache.setItem("savedHunter", this.savedHunter);
        this.emit(GDef.wdEvent.updateCastHunter);
    }

    getEggList() {
        return this.eggList;
    }
    removeEgg(tid: number, time: number) {
        console.log("removeEgg:" + tid + "," + time);
        console.log(this.eggList);
        for (let i = 0; i < this.eggList.length; i++) {
            if (this.eggList[i].tid == tid && this.eggList[i].time == time) {
                console.log("removeEgg：" + i);
                this.eggList.splice(i, 1);
                LocalCache.setItem("eggList", this.eggList);
                break;
            }
        }
    }
    addEgg(tid: number, node3D: Node) {
        let t = new Date().getTime();
        this.eggList.push({ "tid": tid, "time": t });
        LocalCache.setItem("eggList", this.eggList);
        this.emit(GDef.wdEvent.addEgg, tid, t, node3D);
    }

    addPlayerArm(type: number, tid: number) {
        let pos = this.getPlayerFreeCellIndex();
        if (this.intTeach == 1 && this.getCellEmpty(26)) pos = 26;
        if (pos >= 0) {
            for (let i = 0; i < this.armList.length; i++) {
                if (this.armList[i].pos == pos) {
                    this.armList[i].type = type;
                    this.armList[i].tid = tid;
                    LocalCache.setItem("arm", this.armList);
                    //判断是否解锁新人物
                    this.unlockArm(type, tid);
                    type == GDef.TypeHuman ? this.decSavedHunter() : this.decSavedDino();
                    break;
                }
            }
        }
        return pos;
    }
    setPlayerArm(cellId: number, type: number, tid: number) {
        for (let i = 0; i < this.armList.length; i++) {
            if (this.armList[i].pos == cellId) {
                this.armList[i].type = type;
                this.armList[i].tid = tid;
                console.log("setPlayerArm:" + cellId);
                LocalCache.setItem("arm", this.armList);
                //判断是否解锁新人物
                this.unlockArm(type, tid);
                break;
            }
        }
    }
    decPlayerArm(cellId: number) {
        for (let i = 0; i < this.armList.length; i++) {
            if (this.armList[i].pos == cellId) {
                this.armList[i].type = -1;
                this.armList[i].tid = -1;
                LocalCache.setItem("arm", this.armList);
                break;
            }
        }
        console
    }
    unlockArm(type: number, tid: number) {
        //解锁
        if (type == GDef.TypeDino) {
            let find = false;
            for (let i = 0; i < this.unlockDino.length; i++) {
                if (tid == this.unlockDino[i]) {
                    find = true;
                    break;
                }
            }
            if (!find) {
                console.log("show frame");
                this.unlockDino.push(tid);
                LocalCache.setItem("unlockDino", this.unlockDino);
                this.emit(GDef.wdEvent.showFrameArm, type, tid);
            }
        }
        else if (type == GDef.TypeHuman) {
            let find = false;
            for (let i = 0; i < this.unlockHunter.length; i++) {
                if (tid == this.unlockHunter[i]) {
                    find = true;
                    break;
                }
            }
            if (!find) {
                console.log("show frame");
                this.unlockHunter.push(tid);
                LocalCache.setItem("unlockHunter", this.unlockHunter);
                this.emit(GDef.wdEvent.showFrameArm, type, tid);
            }
        }
    }

    setTeach(num: number) {
        this.intTeach = num;
        LocalCache.setItem("teach", this.intTeach);
    }
    getPlayerFreeCellIndex(): armData {
        //我方猎人恐龙数据
        this.armList = LocalCache.getItem("arm");//获取皮肤数据
        if (!this.armList) this.initPlayerArm();
        for (let i = 0; i < this.armList.length; i++) {
            let info: armData = this.armList[i];
            if (info.tid == -1) return info.pos;
        }
        return -1;
    }
    getCellEmpty(n: number): armData {
        //我方猎人恐龙数据
        this.armList = LocalCache.getItem("arm");//获取皮肤数据
        if (!this.armList) this.initPlayerArm();
        for (let i = 0; i < this.armList.length; i++) {
            let info: armData = this.armList[i];
            if (info.pos == n && info.tid == -1) return true;
        }
        return false;
    }


    /**获取当前关卡 */
    getLevel(): number {
        return this.level;
    }

    /**
     * 当前关卡+1
     */
    addLevel(): void {
        this.level++;
        LocalCache.setItem("level", this.level);
    }
    huntermaxLv(): number {
        return 8;
    }
    dinomaxLv(): number {
        return 9;
    }
    /**获取盲盒恐龙*/
    getMangHeDinoLv(): number {
        if (this.level < 8) return Math.random() > 0.25 ? 2 : 2;
        else if (this.level < 12) return Math.random() > 0.25 ? 2 : (Math.max(2, Math.floor(Math.random() * 3)));
        else if (this.level < 16) return Math.random() > 0.25 ? 2 : (Math.max(2, Math.floor(Math.random() * 4)));
        else if (this.level < 24) return Math.random() > 0.25 ? 2 : (Math.max(2, Math.floor(Math.random() * 5)));
        else if (this.level < 32) return Math.random() > 0.25 ? 2 : (Math.max(2, Math.floor(Math.random() * 6)));
        else return Math.random() > 0.25 ? 2 : (Math.max(2, Math.floor(Math.random() * 7)));
    }
    /**看广告获取猎人*/
    getAdCastHunter(): number {
        if (this.castHunterAdCount == 0) return 1;
        if (this.castHunterAdCount > 0 && this.castHunterAdCount < 4) return 2;
        else return Math.max(2, Math.floor((Math.sqrt(this.castHunterAdCount) + 1) * Math.random()));
    }

    addCastHunterAdCount(): void {
        this.castHunterAdCount++;
        LocalCache.setItem("castHunterAdCount", this.castHunterAdCount);
    }
    getCastHunterAdCount(): number {
        return this.castHunterAdCount;
    }

    /**看广告获取恐龙*/
    getAdCastDino(): number {
        if (this.castDinoAdCount == 0) return 1;
        if (this.castDinoAdCount > 0 && this.castDinoAdCount < 4) return 2;
        else return Math.max(2, Math.floor((Math.sqrt(this.castHunterAdCount) + 1) * Math.random()));
    }

    addCastDinoAdCount(): void {
        this.castDinoAdCount++;
        LocalCache.setItem("castDinoAdCount", this.castDinoAdCount);
    }
    getCastDinoAdCount(): number {
        return this.castDinoAdCount;
    }

    /**获取当前关卡 */
    getBattle(): any {
        // return {"Human":[],"posHuman":[],"Dino":[1,3,5,7,9,11,13,15,17],"posDino":[0,1,2,3,4,5,6,7,8]};
        // return {"Human":[3,3,1,3,5,7,5,3,3],"posHuman":[0,1,2,3,4,5,6,7,8],"Dino":[],"posDino":[]};
        // return this.level;
        let baseArm = this.level + 1 + Math.floor(this.level / 4);
        let ratio = (this.level - 1) / this.level;
        ratio = 1 - Math.pow(ratio, 4);
        if (this.level == 1) baseArm = 3;
        else if (this.level == 2) baseArm = 4;
        else if (this.level == 3) baseArm = 7;
        else if (this.level == 4) baseArm = 12;
        else if (this.level == 5) baseArm = 15;
        else if (this.level == 6) baseArm = 19;
        else if (this.level == 7) baseArm = 24;
        else if (this.level == 8) baseArm = 27;
        else if (this.level == 9) baseArm = 30;
        else if (this.level == 10) baseArm = 33;
        else if (this.level == 11) baseArm = 36;
        else if (this.level == 12) baseArm = 40;
        else if (this.level == 13) baseArm = 43;
        else if (this.level == 14) baseArm = 46;
        else if (this.level == 15) baseArm = 49;
        else {
            baseArm = 50;
            for (let i = 0; i < this.level - 15; i++) {
                baseArm += Math.max(2, (baseArm - 40) * ratio);
            }
            baseArm = Math.floor(baseArm);
        }
        console.log("baseArm:" + baseArm);
        let arrBossLevel = [1, 4, 7, 8, 16, 32, 64, 96, 128, 160, 192, 256, 320, 400, 512];
        let arrBossNum = [1, 4, 8, 12, 18, 24, 32, 40, 48, 64, 96, 128, 160, 192, 256, 320];
        let maxBossLevel = 1;
        let maxBossNum = 1;
        for (let i = 0; i < arrBossLevel.length; i++) {
            maxBossLevel = i + 1;
            if (this.level <= arrBossLevel[i]) break;
        }
        for (let i = 0; i < arrBossNum.length; i++) {
            maxBossNum = i + 1;
            if (this.level <= arrBossNum[i]) break;
        }
        let posBack = [2, 1, 3, 0, 4];
        let posFront = [12, 11, 13, 7, 6, 8, 10, 14, 5, 9];
        let arrHuman = [];
        let arrDino = [];
        let arrPosHuman = [];
        let arrPosDino = [];
        let index = 0;
        let countBoss = 0;
        while (baseArm > 0) {
            let bigLevel = Math.min((index % 2 == 0 ? this.huntermaxLv() : this.dinomaxLv()), maxBossLevel);
            let lv = bigLevel;
            if (countBoss < maxBossNum) {
                while (baseArm < Math.pow(2, bigLevel - 1) * 2) {
                    bigLevel--;
                    lv = bigLevel;
                }
            }
            else {
                bigLevel = 1;
                lv = 1;
            }


            if (lv < 1) break;
            else baseArm -= Math.pow(2, bigLevel - 1);


            if (index % 2 == 0 && posBack && posBack.length > 0) {
                arrHuman.push(lv * 2 - 1);
                arrPosHuman.push(posBack[0]);
                posBack.splice(0, 1);
            }
            else if (posFront && posFront.length > 0) {
                arrDino.push(lv * 2 - 1);
                arrPosDino.push(posFront[0]);
                posFront.splice(0, 1);
            }
            else break;

            if (lv > 1) countBoss++;

            index++;
        }
        // {"Tid":4,"Human":[1,3,1],"posHuman":[1,2,3],"Dino":[3,3],"posDino":[11,13]}
        return { "Human": arrHuman, "posHuman": arrPosHuman, "Dino": arrDino, "posDino": arrPosDino };
    }


    /**获取上一个场景 */
    getLastScene(): number {
        return Math.floor((this.level - 1) / 4) % 2;
    }
    /**获取当前场景 */
    getScene(): number {
        // return Math.floor(this.level / 2) % 2;
        return 0;
    }

    //获取当前金币
    getCoin(): number {
        return this.coinNum;
    }

    //清空当前关卡金币
    resetRoundCoin(): void {
        this.roundCoin = 0;
    }
    //清空当前关卡金币
    addRoundCoin(n: number): void {
        console.log("addRoundCoin:" + n);
        this.roundCoin += n;
    }
    //当前关卡金币
    setRoundCoin(n: number): void {
        console.log("setRoundCoin:" + n);
        this.roundCoin = n;
    }
    //获取当前关卡金币
    getRoundCoin(): number {
        return this.roundCoin;
    }

    /**
     * 设置金币
     */
    addCoin(num: number): void {
        this.coinNum = Math.floor(num) + Math.floor(this.coinNum);
        LocalCache.setItem("coin", this.coinNum);
        this.emit(GDef.wdEvent.updateCastDino);
        this.emit(GDef.wdEvent.updateCastHunter);
    }

    /**获取我方队伍 */
    getArm(): number {
        return this.armList;
    }
    //召唤猎人
    addCastHuman(): void {
        this.castHuman++;
        LocalCache.setItem("castHuman", this.castHuman);
    }
    //召唤恐龙
    addCastDino(): void {
        this.castDino++;
        LocalCache.setItem("castDino", this.castDino);
    }
    getCastHuman(): number {
        return this.castHuman;
    }
    getCastDino(): number {
        return this.castDino;
    }
    getCastHumanCost(): number {
        let a1 = this.castHuman;
        let adiv2 = Math.floor(a1 / 3) * 10;
        let adiv5 = Math.floor(a1 / 5) * 50;
        let adiv10 = Math.floor(a1 / 10) * 100;
        let adiv20 = Math.floor(a1 / 20) * 200;
        let adiv40 = Math.floor(a1 / 40) * 400;
        let adiv80 = Math.floor(a1 / 80) * 800;
        let adiv160 = Math.floor(a1 / 160) * 1600;
        let adiv320 = Math.floor(a1 / 320) * 3200;
        let adiv640 = Math.floor(a1 / 640) * 6400;
        let adiv1280 = Math.floor(a1 / 1280) * 1280;
        let adiv2560 = Math.floor(a1 / 2560) * 2560;
        let adiv5120 = Math.floor(a1 / 5120) * 5120;
        let base = 20 + adiv2 + adiv5 + adiv10 + adiv20 + adiv40 + adiv80 + adiv160 + adiv320 + adiv640 + adiv1280 + adiv2560 + adiv5120;

        return Math.max(20, a1 * base);
    }
    getCastDinoCost(): number {
        let a1 = this.castDino;
        let adiv2 = Math.floor(a1 / 3) * 10;
        let adiv5 = Math.floor(a1 / 5) * 50;
        let adiv10 = Math.floor(a1 / 10) * 100;
        let adiv20 = Math.floor(a1 / 20) * 200;
        let adiv40 = Math.floor(a1 / 40) * 400;
        let adiv80 = Math.floor(a1 / 80) * 800;
        let adiv160 = Math.floor(a1 / 160) * 1600;
        let adiv320 = Math.floor(a1 / 320) * 3200;
        let adiv640 = Math.floor(a1 / 640) * 6400;
        let adiv1280 = Math.floor(a1 / 1280) * 1280;
        let adiv2560 = Math.floor(a1 / 2560) * 2560;
        let adiv5120 = Math.floor(a1 / 5120) * 5120;
        let base = 20 + adiv2 + adiv5 + adiv10 + adiv20 + adiv40 + adiv80 + adiv160 + adiv320 + adiv640 + adiv1280 + adiv2560 + adiv5120;

        return Math.max(20, a1 * base);
    }

    getOnlineTime(): number {
        return this.intOnlineTime;
    }

    setOnlineTime(n: number): void {
        this.intOnlineTime = n;
        LocalCache.setItem("onlineTime", this.intOnlineTime);
    }

    /**上线后删除打印 */
    logDevelop() {
        console.log = function () { };
        console.error = function () { };
        cc.log = function () { };
        cc.error = function () { }
    }

    protected emit(eKey, ...parameters: any[]) {
        let a = Notifications.emit(eKey, ...parameters);
        if (a) {
            return a;
        }
    }
}

export default new GD;
